package com.cqhz.quwan.util;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 说    明： 组合工具类
 * 创 建 人：	一刀·胡
 * 创建时间：	2018/5/15 13:42
 * 修 改 人：
 * 修改日期：
 **/
public class Combination<T> {
    private Class<T> type;
    private T[] datas;

    public Combination(T[] datas) {
        this.datas = datas;
        type = (Class<T>) datas.getClass().getComponentType();
    }


    private  <T> T[] newArray( int newLength) {
        return ((T[]) Array.newInstance(type, newLength));
    }

    public List<T[]> select(int m) {
        List<T[]> result = new ArrayList((int)combine(this.datas.length, m));
        this.select(0, (T[]) newArray(m), 0, result);
        return result;
    }

    private void select(int dataIndex, T[] resultList, int resultIndex, List<T[]> result) {
        int resultLen = resultList.length;
        int resultCount = resultIndex + 1;
        if (resultCount > resultLen) {
            result.add(Arrays.copyOf(resultList, resultList.length));
        } else {
            for(int i = dataIndex; i < this.datas.length + resultCount - resultLen; ++i) {
                resultList[resultIndex] = this.datas[i];
                this.select(i + 1, resultList, resultIndex + 1, result);
            }
        }
    }

    // 组合(C 下标m,上标n)
    private static long combine(int m, int n) {
        if (m < n || n < 0) {
            return 0L;
        }
        return factorial(m, m - n + 1) / factorial(n, 1);
    }

    // 阶乘
    private static long factorial(long max, long min) {
        if (max >= min && max > 1) {
            return max * factorial(max - 1, min);
        } else {
            return 1L;
        }
    }

    //排列
    private static long permutation(long max, long min) {
        if (max >= min && min > 0) {
            return max * permutation(max - 1, min - 1);
        } else {
            return 1L;
        }
    }

}
